/**
 * strictc - the Strict compiler
 * Copyright (C) 2008 David Olsson (vonolsson@gmail.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#if !defined(__STRICTAPI_H__)
#define __STRICTAPI_H__

#if defined(__cplusplus)
extern "C" {
#endif

#include <antlr3.h>

typedef struct StrictHandle StrictHandle;

typedef enum {
    SR_OK,
    SR_OUTOFMEMORY,
    SR_LANGERROR
} StrictResult;

typedef enum {
    AM_PUBLIC,
    AM_PRIVATE
} AccessModifier;

typedef enum {
    PM_BOOLEAN,
    PM_BYTE,
    PM_CHAR,
    PM_SHORT,
    PM_INT,
    PM_LONG,
    PM_FLOAT,
    PM_DOUBLE,
    PM_VOIDPTR
} PrimitiveType;

typedef enum {
    CC_STRICTCALL,
    CC_CDECL,
    CC_STDCALL,
    CC_MSFASTCALL
} CallingConvention;

typedef struct {
    ANTLR3_BOOLEAN isPrimitiveType;
    union {
        const ANTLR3_CHAR *typeName;
        PrimitiveType primitiveType;
    };
    
    ANTLR3_UINT32 levelOfIndirection;
    ANTLR3_BOOLEAN isReference;
    
    ANTLR3_BOOLEAN isPtrOrRefConst;
    ANTLR3_BOOLEAN isTargetConst;
    
    ANTLR3_UINT64 arraySize;
} StrictType;

typedef struct {
    ANTLR3_BOOLEAN isVoid;
    StrictType type;
} StrictReturnType;

StrictResult strict_beginSourceFile(StrictHandle *handle, const ANTLR3_CHAR *fileName);
StrictResult strict_endSourceFile(StrictHandle *handle);

StrictResult strict_pushNamespace(StrictHandle *handle, const ANTLR3_CHAR *name);
StrictResult strict_popNamespace(StrictHandle *handle);

StrictResult strict_pushClass(StrictHandle *handle, const ANTLR3_CHAR *name, AccessModifier access, const ANTLR3_CHAR *baseClass, AccessModifier baseClassAccess);
StrictResult strict_addInterfaceToClass(StrictHandle *handle, const ANTLR3_CHAR *name, AccessModifier interfaceAccess);
StrictResult strict_popClass(StrictHandle *handle);

StrictResult strict_beginEnumeration(StrictHandle *handle, const ANTLR3_CHAR *name, AccessModifier access);
StrictResult strict_addEnumerationLiteral(StrictHandle *handle, const ANTLR3_CHAR *name);
StrictResult strict_endEnumeration(StrictHandle *handle);

StrictResult strict_addAttribute(StrictHandle *handle, const ANTLR3_CHAR *name, const StrictType *type);

StrictResult strict_beginMethod(StrictHandle *handle, const ANTLR3_CHAR *name, const StrictReturnType *type, ANTLR3_BOOLEAN isInline, ANTLR3_BOOLEAN isFinal, AccessModifier access, ANTLR3_BOOLEAN isConst);
StrictResult strict_pushParameter(StrictHandle *handle, const ANTLR3_CHAR *name, const StrictType *type);
StrictResult strict_pushException(StrictHandle *handle, const StrictType *type);
StrictResult strict_endMethod(StrictHandle *handle);

StrictResult strict_beginAbstractMethod(StrictHandle *handle, const ANTLR3_CHAR *name, const StrictReturnType *type, ANTLR3_BOOLEAN isConst);
StrictResult strict_endAbstractMethod(StrictHandle *handle);

StrictResult strict_beginFunction(StrictHandle *handle, const ANTLR3_CHAR *name, const StrictReturnType *type, ANTLR3_BOOLEAN isStatic, ANTLR3_BOOLEAN isInline, CallingConvention cc);
StrictResult strict_endFunction(StrictHandle *handle);

StrictResult strict_beginExternalFunctionDefinition(StrictHandle *handle, const ANTLR3_CHAR *name, const StrictReturnType *type, CallingConvention cc);
StrictResult strict_endExternalFunctionDefinition(StrictHandle *handle);

#if defined(__cplusplus)
}
#endif

#endif
